from PyQt5.QtCore import QThread, pyqtSignal
from UI.show_tab_sensor import *
from manager.comManager import *


class WorkThread(QThread):
    signal_info = pyqtSignal(object, object)
    signal_sensor = pyqtSignal(object)

    def __init__(self):
        super(WorkThread, self).__init__()
        self.b_loop = True
        pass

    def __del__(self):
        pass

    def set_loop(self, bloop: bool):
        self.b_loop = bloop

    def run(self):
        while self.b_loop:
            try:
                len_rev, c_info = comManager().receive_data(0)
                print("rev:", c_info)
                if len_rev != 0:
                    self.signal_info.emit(c_info, len_rev)
                    #if Common().get_ap_sta_connect():
                    comManager().station_connect(c_info)
                        #Common().set_ap_sta_connect(False)
                    if Common().get_rev_sensor():
                        dict_sensor = comManager().data_paste(c_info)
                        if len(dict_sensor) != 0:
                            self.signal_sensor.emit(dict_sensor)
                time.sleep(1)
            except Exception as inst:
                print(inst)


class TabCom(object):
    _instance_lock = threading.Lock()
    _first_init = True

    def __init__(self):
        if self._first_init:
            self.ui = None
            self._first_init = False
            self.b_open_com = True
            self.rev_com_info = ""
            self.thread = None
        pass

    def __del__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with cls._instance_lock:
                if not hasattr(cls, '_instance'):
                    TabCom._instance = super().__new__(cls)
        return TabCom._instance

    def init_ui(self, ui):
        self.ui = ui
        self.init_ui_com()
        self.init_connect()

    def init_ui_com(self):
        self.ui.cobox_baud.addItems(['4800', '9600', '14400', '19200', '115200'])
        self.ui.cobox_baud.setCurrentIndex(4)
        self.ui.cobox_parity.addItems(['None', 'Odd', 'Even'])
        self.ui.cobox_parity.setCurrentIndex(0)
        self.ui.cobox_stop.addItems(['1', '2'])
        self.ui.cobox_stop.setCurrentIndex(0)
        self.ui.cobox_data.addItems(['5', '6', '7', '8'])
        self.ui.cobox_data.setCurrentIndex(3)
        self.ui.cobox_end_sign_com.addItems(['CRLF(\\r\\n)', 'CR(\\r)', 'LF(\\n)', 'LF2(\\n\\n)'])
        self.ui.cobox_end_sign_com.setCurrentIndex(0)
        self.ui.btn_fresh.setIcon(QIcon("./res/fresh.png"))
        # self.ui.btn_fresh.setIconSize(QSize(18, 18))
        # self.ui.btn_fresh.setFixedSize(QSize(18, 18))
        # self.ui.btn_fresh.setStyleSheet('border: 5px;')
        self.ui.chbox_save_log_com.setChecked(True)
        self.ui.chbox_end_com.setChecked(True)
        self.ui.chbox_show_str_com.setChecked(True)
        self.ui.chbox_send_str_com.setChecked(True)
        self.show_ports()

    def init_connect(self):
        self.ui.btn_open_close_com.clicked.connect(self.btn_com_open_close_clicked)
        self.ui.btn_send_com.clicked.connect(self.btn_send_com_clicked)
        self.ui.btn_clear_rev_com.clicked.connect(self.btn_clear_rev_com_clicked)
        self.ui.btn_fresh.clicked.connect(self.btn_fresh_com_clicked)
        pass

    def show_ports(self):
        port_dict = comManager.get_com_port()
        self.ui.cobox_com.clear()
        if len(port_dict) == 0:
            self.ui.statusBar.showMessage("No com port!!!")
        else:
            self.ui.cobox_com.addItems(port_dict.keys())
        pass

    def btn_fresh_com_clicked(self):
        self.show_ports()

    def btn_send_com_clicked(self):
        info = self.ui.text_send_com.toPlainText()
        str_end = ""
        if self.ui.chbox_end_com.isChecked():
            if self.ui.cobox_end_sign_com.currentText().find('CRLF') == 0:
                str_end = "\r\n"
            elif self.ui.cobox_end_sign_com.currentText().find('CR') == 0:
                str_end = "\r"
            elif self.ui.cobox_end_sign_com.currentText().find('LF') == 0:
                str_end = "\n"
            elif self.ui.cobox_end_sign_com.currentText().find('LF2') == 0:
                str_end = "\n\n"
        if info != '':
            info += str_end
            # self.recv_com_info += info
            # self.ui.text_rev_com.setText(self.recv_com_info)
            if self.ui.chbox_send_hex_com.isChecked():
                send_type = SEND_TYPE.HEX_SEND
            else:
                send_type = SEND_TYPE.STRING_SEND
            comManager().send_data(send_type, info)

    def btn_clear_rev_com_clicked(self):
        self.ui.text_rev_com.setText("")
        pass

    def btn_com_open_close_clicked(self):
        port_dict = comManager.get_com_port()
        comManager().init_com(port_dict[self.ui.cobox_com.currentText()],
                              int(self.ui.cobox_baud.currentText()),
                              comManager.change_parity(self.ui.cobox_parity.currentText()),
                              int(self.ui.cobox_stop.currentText()),
                              int(self.ui.cobox_data.currentText()))
        if self.b_open_com:  # open
            comManager().open_com_port()
            self.ui.btn_open_close_com.setText("关闭")
            self.b_open_com = False
            self.thread = WorkThread()
            self.thread.signal_info.connect(self.update_info)
            self.thread.signal_sensor.connect(self.update_sensor)
            self.thread.start()
        else:  # close
            self.thread.set_loop(False)
            comManager().close_com_port()
            self.ui.btn_open_close_com.setText("打开")
            self.b_open_com = True

    def update_info(self, info, len_rev):
        is_16_check = self.ui.chbox_show_hex_com.isChecked()
        if len_rev:
            if is_16_check:
                info = Common.bytes_to_str(info)
                pass
            else:
                info = info.decode('utf-8', 'replace')
            print('len_rev:', len_rev)
            info = time.strftime("%Y_%m_%d %H:%M:%S", time.localtime()) + ' ' + info + '\n'
            if self.ui.chbox_save_log_com.isChecked():
                Common.save_txt(info)
            self.rev_com_info = self.rev_com_info + info
            self.ui.text_rev_com.setText(self.rev_com_info)
            self.ui.text_rev_com.moveCursor(self.ui.text_rev_com.textCursor().End)  # show data in the end

    @staticmethod
    def update_sensor(dict_sensor):
        TabSensor().update_sensor_status(dict_sensor)

